import { sleep } from "@/utils";
import IpcParams from "../IpcParams";
import { createAgent } from './utils';
import Axios from 'axios';
import axiosRetry from 'axios-retry';

export default class MajorGame {
  constructor(tokenInfo) {
    this.tokenInfo = tokenInfo
    const agent = createAgent(this.tokenInfo.proxy)
    const headers = {
      "Referer": "https://major.bot/?tgWebAppStartParam=7178112614",
      "Content-Type": "application/json",
      "User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 16_7_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148",
    }
    this.axios = Axios.create({
      headers: headers,
      httpAgent: agent,
      httpsAgent: agent,
      timeout: 60 * 1000,
    })
    axiosRetry(this.axios, {
      retries: 3, retryDelay: (retryCount) => {
        return 2000
      }
    });
  }

  async run() {
    try {
      let webSessionUrl = this.tokenInfo.tgweb
      if (webSessionUrl.startsWith("https://") == false) {
        console.error(`${this.gameInfo.phone}  error session url ${webSessionUrl}`);
        return
      }
      webSessionUrl = decodeURIComponent(webSessionUrl)
      let session = webSessionUrl.split("#tgWebAppData=")[1]
      session = session.split("&tgWebAppVersion")[0]
      // auth
      const authTgRes = await this.axios.request("https://major.bot/api/auth/tg/", {
        method: "post",
        data: {
          init_data: session,
        }
      })
      const accessToken = authTgRes.data.access_token
      this.user = authTgRes.data.user
      const headers = {
        authorization: "Bearer " + accessToken,
      }
      this.headers = headers

      await this.refreshUser()

      // 每日签到
      await this.userVisits()

      await sleep(1000)

      await this.holdCoins()

      await this.playSpin()

      await this.swipeCoin()

      await this.dailyTask()

      await this.oneTimeTask()

      await this.refreshUser()

      this.tokenInfo.score = this.user.rating
      const date = (new Date()).toLocaleString()
      this.tokenInfo.gameupdate = date
      this.tokenInfo.count = (this.tokenInfo.count || 0) + 1
      console.log(date, "major end", this.tokenInfo.phone, "score: ", this.tokenInfo.score)
      return new IpcParams("runMajor", this.tokenInfo)
    } catch (error) {
      console.log((new Date()).toLocaleString(), "major error", this.tokenInfo.phone)
      if (error.response) {
        console.error(error.request.path, error.response)
      } else {
        console.error(error)
      }
      return new IpcParams("runMajor", this.tokenInfo, error)
    }
  }

  async userVisits() {
    try {
      const visitsRes = await this.axios.request("https://major.bot/api/user-visits/streak/", {
        method: "get",
        headers: this.headers,
      })
      if (visitsRes.data.streak == 0) {
        await this.axios.request("https://major.bot/api/user-visits/visit/", {
          method: "post",
          headers: this.headers,
        })
      }
    } catch (error) {
      console.error(error)
    }
  }

  async refreshUser() {
    try {
      const userRes = await this.axios.request(`https://major.bot/api/users/${this.user.id}/`, {
        method: "get",
        headers: this.headers,
      })
      this.user = userRes.data
    } catch (error) {
      console.error(error)
    }
  }

  async dailyTask() {
    try {
      const taskListRes = await this.axios.request("https://major.bot/api/tasks/?is_daily=true", {
        method: "get",
        headers: this.headers,
      })
      const taskList = taskListRes.data
      for (let index = 0; index < taskList.length; index++) {
        const element = taskList[index];
        if (element.is_completed == true) {
          continue;
        }
        try {
          const taskRes = await this.axios.request("https://major.bot/api/tasks/", {
            method: "post",
            headers: this.headers,
            data: {
              task_id: element.id,
            }
          })
          console.log("finish task", taskRes.data)
        } catch (error) {
          error.response && console.error(error.response.data)
        }
        await sleep(Math.random() * 500 + 500)
      }
    } catch (error) {
      console.error(error)
    }
  }

  async oneTimeTask() {
    try {
      const taskListRes = await this.axios.request("https://major.bot/api/tasks/?is_daily=false", {
        method: "get",
        headers: this.headers,
      })
      const taskList = taskListRes.data
      for (let index = 0; index < taskList.length; index++) {
        const element = taskList[index];
        if (element.is_completed == true) {
          continue;
        }
        try {
          const taskRes = await this.axios.request("https://major.bot/api/tasks/", {
            method: "post",
            headers: this.headers,
            data: {
              task_id: element.id,
            }
          })
          console.log("finish task", taskRes.data)
        } catch (error) {
          error.response && console.error(error.response.data)
        }

        await sleep(Math.random() * 500 + 500)
      }
    } catch (error) {
      console.error(error)
    }
  }

  async holdCoins() {
    try {
      const startRes = await this.axios.request("https://major.bot/api/bonuses/coins/", {
        method: "get",
        headers: this.headers,
      })
      const success = startRes.data.success
      if (success != true) {
        return
      }
      await sleep(5500)
      const endRes = await this.axios.request("https://major.bot/api/bonuses/coins/", {
        method: "post",
        headers: this.headers,
        data: {
          coins: 885
        }
      })
      console.log("holdCoins", endRes.data)
    } catch (error) {
      if (error.response) {
        console.error("holdCoins", error.response.data)
      } else {
        console.error("holdCoins", error)
      }
    }
  }

  async playSpin() {
    try {
      const startRes = await this.axios.request("https://major.bot/api/roulette/", {
        method: "get",
        headers: this.headers,
      })
      const success = startRes.data.success
      if (success != true) {
        return
      }
      await sleep(5500)
      const endRes = await this.axios.request("https://major.bot/api/roulette/", {
        method: "post",
        headers: this.headers,
        data: {}
      })
      console.log("playSpin", endRes.data)
    } catch (error) {
      if (error.response) {
        console.error("playSpin", error.response.data)
      } else {
        console.error("playSpin", error)
      }
    }
  }

  async swipeCoin() {
    try {
      const startRes = await this.axios.request("https://major.bot/api/swipe_coin/", {
        method: "get",
        headers: this.headers,
      })
      const success = startRes.data.success
      if (success != true) {
        return
      }
      await sleep(5500)
      const coins = Math.floor(Math.random() * 300 + 1200)
      const endRes = await this.axios.request("https://major.bot/api/swipe_coin/", {
        method: "post",
        headers: this.headers,
        data: {
          coins: coins
        }
      })
      console.log("swipeCoin", coins, endRes.data)
    } catch (error) {
      if (error.response) {
        console.error("swipeCoin", error.response.data)
      } else {
        console.error("swipeCoin", error)
      }
    }
  }
}
